<?php
/**
 * Author: ChenGuangHui
 * Email：13035809409@163.com
 * Date Time: 2021/4/30 11:35
 */


namespace App\Logic\Staffer;


use App\Enums\HttpCode;
use App\Logic\CommLogic;
use App\Models\Rbac\RbacRole;
use App\Models\Staffer\Staffer;
use App\Notifications\RegisterNotify;
use App\Services\OaService\OaFactory;
use Arr;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Hash;

class StafferLogic extends CommLogic
{
    /**
     * @param $params
     * @return mixed
     */
    public function lists($params)
    {
        $query = Staffer::query()
            ->with('tenant')
            ->when(isset($params['status']), function (Builder $query) use ($params) {
                $query->where('status', $params['status']);
            })
            ->when(!empty($params['name']), function (Builder $query) use ($params) {
                $query->where('name', 'like', '%' . $params['name'] . '%');
            });

        if (!empty($sortData)) {
            $query = $query->orderBy($sortData['sortRow'], $sortData['sortType']);
        }else{
            $query = $query->orderBy('id', 'desc');
        }

        $data = $query->get()->toArray();
        return $data;
    }

    /**
     * @param array $where
     * @param array $pageData
     * @param array $sortData
     * @return \Illuminate\Http\JsonResponse
     */
    public function index($where = [], $pageData = ['pageSize' => 20, 'pageNow' => 1], $sortData = [])
    {
        $query = Staffer::query()
            ->with('tenant')
            ->when(isset($where['status']), function (Builder $query) use ($where) {
                $query->where('status', $where['status']);
            })
            ->when(!empty($where['name']), function (Builder $query) use ($where) {
                $query->where('name', '%' . $where['name'] . '%');
            });

        if (!empty($sortData)) {
            $query = $query->orderBy($sortData['sortRow'], $sortData['sortType']);
        }else{
            $query = $query->orderBy('id', 'desc');
        }

        $data = $query->paginate($pageData['pageSize'], ['*'], 'page', $pageData['pageNow'])
            ->toArray();

        $role = RbacRole::query()->whereIn('id', explode(',', implode(',', array_column($data["data"], 'role_ids'))))->get();
        foreach($data["data"] as &$item){
            $item['avatar_url'] = Arr::first(array_column(json_decode($item['avatar_url'], true), 'url'));
            $item['role_name'] = implode(',', array_column(collect($role)->whereIn('id', explode(',', $item['role_ids']))->toArray(), 'name'));
        }
        
        return $data;
    }

    /**
     * @param $params
     * @return bool
     * @throws \Throwable
     */
    public function store($params)
    {
        $lockName = 'staffer_store_' . auth('api')->id();
        $lock = \Cache::lock($lockName, 5);
        abort_if(!$lock->get(), HttpCode::TOO_MANY_REQUESTS, '请勿重复操作！');
        \DB::beginTransaction();
        try {
            $data = array(
                'name' => $params['name'],
                'sex' => $params['sex'] ?? 0,
                'staffer_no' => $params['staffer_no'],
                'mobile' => $params['mobile'],
                'role_ids' =>  implode(',', $params['role_ids']),
                'password' => isset($params['password']) ? bcrypt($params['password']) : bcrypt(123456),
                'email' => $params['email'],
                'status' => $params['status'] ? 1 : 0,
                'tenant_id' => $params['tenant_id'],
                'avatar_url' => json_encode($params['avatar_url'], true),
                'register_ip' => get_client_ip(),
                'remark' => $params['remark'] ?? '',
            );
            $staffer = Staffer::query()->create($data);
            // 消息提醒
            $staffer->notify((new RegisterNotify($staffer)));
            \DB::commit();
        } catch (QueryException $exception) {
            \DB::rollBack();
            throw new \Exception($exception->getMessage(), $exception->getCode());
        }
        return true;
    }

    /**
     * @param $params
     * @param $id
     * @return Staffer|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function show($params, $id)
    {
        $staffer = Staffer::query()->where('id', $id)->first();
        abort_if(empty($staffer), HttpCode::FORBIDDEN, '找不到员工');
        RbacRole::query()->whereIn('id', explode(',', $staffer->role_ids))->get();
        $role_ids = array();
        foreach(explode(",", $staffer->role_ids) as $id){
            $role_ids[] = intval($id);
        }
        $staffer->status = $staffer->status == 1 ? true : false;
        $staffer->role_ids = $role_ids;
        $staffer->avatar_url = json_decode($staffer->avatar_url, true);
        return $staffer;
    }

    /**
     * @param $params
     * @param $id
     * @return bool
     * @throws \Throwable
     */
    public function update($params, $id)
    {
        $lockName = 'staffer_update_' . auth('api')->id();
        $lock = \Cache::lock($lockName, 5);
        abort_if(!$lock->get(), HttpCode::TOO_MANY_REQUESTS, '请勿重复操作！');

        $staffer = Staffer::query()->where('id', $id)->first();
        abort_if(empty($staffer), HttpCode::FORBIDDEN, '找不到员工');
        \DB::beginTransaction();
        try {
            $data = array(
                'mobile' => $params['mobile'],
                'name' => $params['name'],
                'nickname' => $params['nickname'],
                'tenant_id' => $params['tenant_id'],
                'status' => $params['status'] ? 1 : 0,
                'role_ids' => implode(',', $params['role_ids']),
                'email' => $params['email'],
                'avatar_url' => json_encode($params['avatar_url'], true),
                'remark' => $params['remark'] ?? '',
            );
            if(isset($params['password'])){
                $data["password"] = bcrypt($params['password']);
            }
            $staffer->update($data);
            \DB::commit();
        } catch (QueryException $exception) {
            \DB::rollBack();
            throw new \Exception($exception->getMessage(), $exception->getCode());
        }
        return true;
    }

    /**
     * @param $id
     * @return bool
     * @throws \Throwable
     */
    public function destroy($id)
    {
        $data = Staffer::query()->where('id', $id)->first();
        abort_if(empty($data), HttpCode::FORBIDDEN, '找不到员工');
        \DB::beginTransaction();
        try {
            $data->delete();
            \DB::commit();
        } catch (QueryException $exception) {
            \DB::rollBack();
            throw new \Exception($exception->getMessage(), $exception->getCode());
        }
        return true;
    }
}
